package com.tuniu.agents.config;

import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.tuniu.agents.advisor.StreamingToolCallingManager;
import com.tuniu.agents.agent.AgentManager;
import com.tuniu.agents.agent.SpringAgentManager;
import com.tuniu.agents.common.IdGenerator;
import com.tuniu.agents.common.RequestIdGenerator;
import com.tuniu.agents.common.message.MessageMemorySenderManager;
import com.tuniu.agents.common.message.MessageSenderManager;
import com.tuniu.agents.memory.ChatMemoryManager;
import com.tuniu.agents.memory.MemoryManager;
import com.tuniu.agents.message.MessageMemoryManager;
import com.tuniu.agents.message.MessageSender;
import com.tuniu.agents.prompt.ResourcePromptManager;
import com.tuniu.agents.util.HttpManager;
import com.tuniu.agents.util.OKHttpManager;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.model.tool.ToolCallingManager;
import org.springframework.ai.tool.execution.ToolExecutionExceptionProcessor;
import org.springframework.ai.tool.resolution.ToolCallbackResolver;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class SpringAiConfig {
    @Bean("agentManager")
    public AgentManager agentManager() {
        return new SpringAgentManager();
    }

    @Bean
    public ResourcePromptManager resourcePromptManager(ResourcePatternResolver resourcePatternResolver) {
        return new ResourcePromptManager(resourcePatternResolver);
    }

    @Bean
    public ChatMemoryManager chatMemoryManager(ChatMemory chatMemory) {
        return new ChatMemoryManager(chatMemory);
    }

    @Bean
    public HttpManager webClientManager() {
        return new OKHttpManager();
    }

    @Bean
    public WebClient webClient() {
        return WebClient.builder().build();
    }


    @Bean
    public IdGenerator idGenerator() {
        return new RequestIdGenerator();
    }

    @Bean
    public ToolCallingManager toolCallingManager(ToolCallbackResolver toolCallbackResolver,
                                                 ToolExecutionExceptionProcessor toolExecutionExceptionProcessor,
                                                 ObjectProvider<ObservationRegistry> observationRegistry) {
        return new StreamingToolCallingManager(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP), toolCallbackResolver, toolExecutionExceptionProcessor);
    }

    @Bean(name="messageSender")
    public MessageSender messageSender() {
        //return new LoggingMessageSender();
        return new MessageSenderManager();
    }

    @Bean(name="messageMemoryManager")
    public MessageMemoryManager messageMemoryManager(MessageSender messageSender, MemoryManager memoryManager) {
        return new MessageMemorySenderManager(memoryManager, messageSender);
    }

    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper().registerModule(new JavaTimeModule()).configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
    }

}
